#include "ImageSettingUi.h"
#include "ui_ImageSettingUi.h"
#include "WidgetHandler.h"
#include "MiscData.h"
#include "LogoUtility.h"
#include "ImageSetting.h"
#include "ItemMap.cpp"
#include "AuthorityDialog.h"
#include "Mcu.h"
#include "Fpga.h"
#ifdef arm
#include "Mpp.h"
#endif
#include "SensorInfo.h"

ImageSettingUi::ImageSettingUi(QWidget *parent) :
    BaseWidget(parent),
    ui(new Ui::ImageSettingUi)
{
    ui->setupUi(this);
    LogoUtility::getInstance()->addLogoLabel(ui->logo);
    ui->image->installEventFilter(this);
    ui->clippedMode0->hide();
    ui->clippedMode1->hide();
    ui->clippedMode2->hide();
    ui->label->setVisible(false);
    ui->settingItem4->setVisible(false);
    ui->settingItem11->setVisible(false);
    QObject::connect(ui->settingItem0, &ImageSettingItem::syncValueSignal, this, &ImageSettingUi::syncValueSlot);
    QObject::connect(ui->settingItem1, &ImageSettingItem::syncValueSignal, this, &ImageSettingUi::syncValueSlot);
    QObject::connect(ui->settingItem2, &ImageSettingItem::syncValueSignal, this, &ImageSettingUi::syncValueSlot);
    QObject::connect(ui->settingItem3, &ImageSettingItem::syncValueSignal, this, &ImageSettingUi::syncValueSlot);
    QObject::connect(ui->settingItem4, &ImageSettingItem::syncValueSignal, this, &ImageSettingUi::syncValueSlot);

    QObject::connect(ui->settingItem5, &ImageSettingItem::syncValueSignal, this, &ImageSettingUi::syncValueSlot);
    QObject::connect(ui->settingItem6, &ImageSettingItem::syncValueSignal, this, &ImageSettingUi::syncValueSlot);
    QObject::connect(ui->settingItem7, &ImageSettingItem::syncValueSignal, this, &ImageSettingUi::syncValueSlot);
    QObject::connect(ui->settingItem8, &ImageSettingItem::syncValueSignal, this, &ImageSettingUi::syncValueSlot);
    QObject::connect(ui->settingItem9, &ImageSettingItem::syncValueSignal, this, &ImageSettingUi::syncValueSlot);
    QObject::connect(ui->settingItem11, &ImageSettingItem::syncValueSignal, this, &ImageSettingUi::syncValueSlot);

    QObject::connect(ui->settingItemDLC, &ImageSettingItem::syncValueSignal, this, &ImageSettingUi::syncValueSlot);
    QObject::connect(ui->settingItemDPC, &ImageSettingItem::syncValueSignal, this, &ImageSettingUi::syncValueSlot);
    QObject::connect(ui->settingItemLens, &ImageSettingItem::syncValueSignal, this, &ImageSettingUi::syncValueSlot);

    g_syncTimer = new QTimer();
    QObject::connect(g_syncTimer, &QTimer::timeout, this, &ImageSettingUi::syncTimerSlot);
    g_syncTimer->setSingleShot(true);
    loadSettingItemUiInfo();

    int mirrorType = RuntimeData::BootSetting::getInstance()->g_bootSettingInfo.currentMirrorType;
    mirrorTypeBtn.addButton(ui->mirror0, 0);
    mirrorTypeBtn.addButton(ui->mirror1, 1);
    mirrorTypeBtn.addButton(ui->mirror2, 2);
    mirrorTypeBtn.addButton(ui->mirror3, 3);
    mirrorTypeBtn.addButton(ui->mirror4, 4);
    mirrorTypeBtn.addButton(ui->mirror5, 5);
    mirrorTypeBtn.button(mirrorType)->click();
    connect(&mirrorTypeBtn, SIGNAL(buttonClicked(int)), SLOT(changeMirrorTypeSlot(int)));

    ledState.addButton(ui->led_off, 0);
    ledState.addButton(ui->led_on, 1);
    connect(&ledState, SIGNAL(buttonClicked(int)), SLOT(ledStateSlot(int)));

    clippedMode.addButton(ui->clippedMode0, 0);
    clippedMode.addButton(ui->clippedMode1, 1);
    clippedMode.addButton(ui->clippedMode2, 2);
    qDebug()<<"clip"<<RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][10];
    clippedMode.button(RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][10])->click();
    connect(&clippedMode, SIGNAL(buttonClicked(int)), SLOT(clippedModeSlot(int)));

    syncValueToUi();

    QObject::connect(AuthorityDialog::getInstance(), &AuthorityDialog::ImageSettingUi_Save_Signal, this, &ImageSettingUi::ImageSettingUi_Save_Slot);


    connect(&SensorInfo::getInstance(),&SensorInfo::sensorTypeChanged, [&](){
        uint32_t v =  SensorInfo::getInstance().getSensorType();
        setMaskType();
        if(v != 0x00) {
            bool isVisible = (v == 0X69 ? true:false);
            this->ui->label->setVisible(isVisible);
            this->ui->settingItem4->setVisible(isVisible);
            this->ui->clippedMode0->setVisible(isVisible);
            this->ui->clippedMode1->setVisible(isVisible);
            this->ui->clippedMode2->setVisible(isVisible);
            this->ui->settingItem11->setVisible(isVisible);
        }
        int mirrorType = RuntimeData::BootSetting::getInstance()->g_bootSettingInfo.currentMirrorType;
        for (int i = 0; i < IMAGE_SETTING_ITEM_COUNT; i++) {
            if(i!=10)
            setFpga[i](RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][i], v);
        }
        setFpga[9](11, 0);//打开LED；
    });

    connect(Mcu::getInstance(), &Mcu::reportSensorRegisterValue, [&](uint8_t val){
        ui->lineEdit_4->setText(QString("%1").arg(val,1,16));
    });
    ui->RegisterPage->hide();
}

ImageSettingUi::~ImageSettingUi()
{
    delete ui;
}

void ImageSettingUi::activate()
{
    setMaskType();
    ui->image_2->setVisible(RuntimeData::MiscData::getInstance()->g_miscDataInfo.openCrossLine);
    int mirrorType = RuntimeData::BootSetting::getInstance()->g_bootSettingInfo.currentMirrorType;
    Mpp::getInstance()->startRealtimeImage();
    mirrorTypeBtn.button(mirrorType)->click();
    if(SensorInfo::getInstance().getIsOpenRegisterOperationPage()) {
        m_pages = 3;
        ui->RegisterPage->show();
    } else {
        m_pages = 2;
        ui->RegisterPage->hide();
    }
    syncValueToUi();
}

void ImageSettingUi::inactivate()
{
    int mirrorType = RuntimeData::BootSetting::getInstance()->g_bootSettingInfo.currentMirrorType;
    mirrorTypeBtn.button(mirrorType)->click();
    setMaskType();
}

void ImageSettingUi::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        loadSettingItemUiInfo();
        break;

    default:
        break;
    }
}

bool ImageSettingUi::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == ui->image && event->type() == QEvent::MouseButtonPress) {
        RuntimeData::MiscData::getInstance()->g_miscDataInfo.fullScreenEntryType = 1;
        //hide();/* 全屏显示 */
    }
}

void ImageSettingUi::loadSettingItemUiInfo()
{

    ui->settingItem0->setItemId(ImageSaturability_Index);
    ui->settingItem1->setItemId(ImageColorR_Index);
    ui->settingItem2->setItemId(ImageColorB_Index);
    ui->settingItem3->setItemId(ImageSharpness_Index);
    ui->settingItem4->setItemId(ImageCalibration_Index);
    ui->settingItem5->setItemId(ImageGamma_Index);
    ui->settingItem6->setItemId(ImageDenoise_Index);
    ui->settingItem7->setItemId(ImageContrast_Index);
    ui->settingItem8->setItemId(ImageBrightness_Index);
    ui->settingItem9->setItemId(Ledbrightness_Index);
    ui->settingItem11->setItemId(StripeCorrect_Index);
    ui->settingItemDLC->setItemId(ImageDLC);
    ui->settingItemDPC->setItemId(ImageDPC);
    ui->settingItemLens->setItemId(ImageLens);

    ui->settingItem0->setItemTitle(QApplication::translate("QObject",m_settingItem.value(ImageSaturability_Index),Q_NULLPTR));
    ui->settingItem1->setItemTitle(QApplication::translate("QObject",m_settingItem.value(ImageColorR_Index),Q_NULLPTR));
    ui->settingItem2->setItemTitle(QApplication::translate("QObject",m_settingItem.value(ImageColorB_Index),Q_NULLPTR));
    ui->settingItem3->setItemTitle(QApplication::translate("QObject",m_settingItem.value(ImageSharpness_Index),Q_NULLPTR));
    ui->settingItem4->setItemTitle(QApplication::translate("QObject",m_settingItem.value(ImageCalibration_Index),Q_NULLPTR));
    ui->settingItem5->setItemTitle(QApplication::translate("QObject",m_settingItem.value(ImageGamma_Index),Q_NULLPTR));
    ui->settingItem6->setItemTitle(QApplication::translate("QObject",m_settingItem.value(ImageDenoise_Index),Q_NULLPTR));
    ui->settingItem7->setItemTitle(QApplication::translate("QObject",m_settingItem.value(ImageContrast_Index),Q_NULLPTR));
    ui->settingItem8->setItemTitle(QApplication::translate("QObject",m_settingItem.value(ImageBrightness_Index),Q_NULLPTR));
    ui->settingItem9->setItemTitle(QApplication::translate("QObject",m_settingItem.value(Ledbrightness_Index),Q_NULLPTR));
    ui->settingItem11->setItemTitle(QApplication::translate("QObject",m_settingItem.value(StripeCorrect_Index),Q_NULLPTR));

    ui->settingItemDLC->setItemTitle(QApplication::translate("QObject",m_settingItem.value(ImageDLC),Q_NULLPTR));
    ui->settingItemDPC->setItemTitle(QApplication::translate("QObject",m_settingItem.value(ImageDPC),Q_NULLPTR));
    ui->settingItemLens->setItemTitle(QApplication::translate("QObject",m_settingItem.value(ImageLens),Q_NULLPTR));
}

void ImageSettingUi::syncValueSlot(int id, int type)
{
    Mcu::getInstance()->touchSoundBeepMessage();
    uint32_t t = SensorInfo::getInstance().getSensorType();
    int mirrorType = RuntimeData::BootSetting::getInstance()->g_bootSettingInfo.currentMirrorType;

    int value = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][id];
    value = (type == 0) ? (value -1) : (value + 1);
    checkSettingValue(id, &value);
    RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][id] = value;

    syncValueToUi();
    setFpga[id](value, t);

}

void ImageSettingUi::syncTimerSlot()
{
    int mirrorType = RuntimeData::BootSetting::getInstance()->g_bootSettingInfo.currentMirrorType;
    uint32_t t = SensorInfo::getInstance().getSensorType();
    uint8_t mask = 0x1;
    /* bit0: 保存 */
    if (g_actionType & (mask << 0)) {
        g_actionType = g_actionType & (~mask);
        RuntimeData::ImageSetting::getInstance()->saveImageSettingToRom(mirrorType);
        RuntimeData::BootSetting::getInstance()->saveBootSettingInfoToRom();
        qDebug()<<"save ok";
    }

    mask = 0x1;
    /* bit1: 恢复出厂 */
    if (g_actionType & (mask << 1)) {
        g_actionType = g_actionType & (~(mask << 1));
        qDebug()<<"recover ok";
        RuntimeData::ImageSetting::getInstance()->recoverDefalutImageSettingInfo(mirrorType);
        syncValueToUi();
        for (int i = 0; i < IMAGE_SETTING_ITEM_COUNT; i++) {
            setFpga[i](RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][i], t);
        }
    }
}

void ImageSettingUi::updateImageSettingItemUiSlot()
{
    syncValueToUi();
}

void ImageSettingUi::syncValueToUi() {
    int mirrorType = RuntimeData::BootSetting::getInstance()->g_bootSettingInfo.currentMirrorType;
    int index = 0;

    index = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][ImageSaturability_Index];
    ui->settingItem0->setItemValue(QString("%1").arg(m_saturabilityMap.value(index)));

    index = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][ImageColorR_Index];
    ui->settingItem1->setItemValue(QString("%1").arg(m_colorRMap.value(index)));

    index = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][ImageColorB_Index];
    ui->settingItem2->setItemValue(QString("%1").arg(m_colorBMap.value(index)));

    index = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][ImageSharpness_Index];
    ui->settingItem3->setItemValue(QString("%1").arg(m_sharpnessMap.value(index)));

    index = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][ImageCalibration_Index];
    ui->settingItem4->setItemValue(QString("%1").arg(index));

    index = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][ImageGamma_Index];
    ui->settingItem5->setItemValue(QString("%1").arg(m_gammaMap.value(index)));

    index = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][ImageDenoise_Index];
    ui->settingItem6->setItemValue(QString("%1").arg(m_denoiseMap.value(index)));

    index = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][ImageContrast_Index];
    ui->settingItem7->setItemValue(QString("%1").arg(m_contrastMap.value(index)));

    index = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][ImageBrightness_Index];
    ui->settingItem8->setItemValue(QString("%1").arg(m_brightnessMap.value(index)));

    index = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][Ledbrightness_Index];
    ui->settingItem9->setItemValue(QString("%1").arg(m_ledbrightnessMap.value(index)));

    index = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][StripeCorrect_Index];
    ui->settingItem11->setItemValue(QString("%1").arg(index));

    index = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][ImageDLC];
    ui->settingItemDLC->setItemValue(QString("%1").arg(m_DLCMap.value(index)));

    index = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][ImageDPC];
    ui->settingItemDPC->setItemValue(QString("%1").arg(m_DPCMap.value(index)));

    index = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][ImageLens];
    ui->settingItemLens->setItemValue(QString("%1").arg(m_LensMap.value(index)));


    clippedMode.button(RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][10])->click();
}

void ImageSettingUi::syncValueToMcu()
{

}

void ImageSettingUi::exeAction(uint8_t offset, int msec)
{
    uint8_t mask = 0x1;
    g_actionType = g_actionType | (mask << offset);
    g_syncTimer->start(msec);
}

void ImageSettingUi::on_goback_clicked()
{
    Mcu::getInstance()->touchSoundBeepMessage();
    WidgetHandler::getInstance()->displayWidget(HomeUi_Id);
}

void ImageSettingUi::on_gohome_clicked()
{
    Mcu::getInstance()->touchSoundBeepMessage();
    WidgetHandler::getInstance()->displayWidget(HomeUi_Id);
}

void ImageSettingUi::changeMirrorTypeSlot(int index)
{
    Mcu::getInstance()->touchSoundBeepMessage();
    qDebug()<<"mirrorType = "<<index;
    uint32_t t = SensorInfo::getInstance().getSensorType();
    RuntimeData::ImageSetting::getInstance()->readImageSettingInfoByRom(index);
    RuntimeData::BootSetting::getInstance()->g_bootSettingInfo.currentMirrorType = index;
    syncValueToUi();
    for (int i = 0; i < IMAGE_SETTING_ITEM_COUNT; i++) {
        if(i!=10) setFpga[i](RuntimeData::ImageSetting::getInstance()->g_settingItemValue[index][i], t);
    }

}

void ImageSettingUi::ledStateSlot(int index)
{
    Mcu::getInstance()->touchSoundBeepMessage();
    uint32_t t = SensorInfo::getInstance().getSensorType();
    qDebug()<<"ledState = "<<index;
    setFpga[Ledbrightness_Index](index + 10, t);
}

void ImageSettingUi::clippedModeSlot(int index) {
    Mcu::getInstance()->touchSoundBeepMessage();
    int mirrorType = RuntimeData::BootSetting::getInstance()->g_bootSettingInfo.currentMirrorType;
    RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][10] = index;
    setMaskType();
}

void ImageSettingUi::on_save_clicked()
{
    Mcu::getInstance()->touchSoundBeepMessage();
    int userId = RuntimeData::BootSetting::getInstance()->g_bootSettingInfo.currentUserId;

    if (userId < 0) {
        AuthorityDialog::getInstance()->setParent(this);
        AuthorityDialog::getInstance()->setAuthorityType(AuthorityType_ImageSettingUi_Save);
        AuthorityDialog::getInstance()->exec();
    } else {
        ImageSettingUi_Save_Slot();
    }
}

void ImageSettingUi::on_recover_clicked()
{
    Mcu::getInstance()->touchSoundBeepMessage();
    int userId = RuntimeData::BootSetting::getInstance()->g_bootSettingInfo.currentUserId;

    if (userId < 0) {
        AuthorityDialog::getInstance()->setParent(this);
        AuthorityDialog::getInstance()->setAuthorityType(AuthorityType_ImageSettingUi_Save);
        AuthorityDialog::getInstance()->exec();
    } else {
        Mcu::getInstance()->touchSoundBeepMessage();
        exeAction(1, 800);
    }
}

void ImageSettingUi::ImageSettingUi_Save_Slot()
{
    exeAction(0, 10);
}

void ImageSettingUi::on_left_clicked()
{
    Mcu::getInstance()->touchSoundBeepMessage();
    int index = ui->itemPage->currentIndex();

    index--;
    if (index <= 0)
        index = 0;

    ui->indexTip->setText(QString("%1/2").arg(index+1));
    ui->itemPage->setCurrentIndex(index);
}

void ImageSettingUi::on_right_clicked()
{
    Mcu::getInstance()->touchSoundBeepMessage();
    int index = ui->itemPage->currentIndex();

    index++;
    if (index >= m_pages) index = m_pages-1;

    ui->indexTip->setText(QString("%1/2").arg(index+1));
    ui->itemPage->setCurrentIndex(index);
}

/**
 * @brief ImageSettingUi::写
 */
void ImageSettingUi::on_pushButton_clicked() {
    QString txt = ui->lineEdit->text();
    QString val = ui->lineEdit_2->text();
    Fpga::getInstance()->writeRegister(txt.toUInt(nullptr, 16),val.toUInt(nullptr, 16));
}

/**
 * @brief ImageSettingUi::读
 */
void ImageSettingUi::on_pushButton_2_clicked() {
    QString txt = ui->lineEdit->text();
    auto val = Fpga::getInstance()->readRegister(txt.toUInt(nullptr, 16));
    ui->lineEdit_2->setText(QString("%1").arg(val,1,16));
}

/**
 * @brief ImageSettingUi::写Sensor
 */
void ImageSettingUi::on_pushButton_3_clicked() {
    SensorRegisterOperationPkg pkg;
    QString txt = ui->lineEdit_3->text();
    QString val = ui->lineEdit_4->text();
    pkg.operation = 1;
    pkg.addr = txt.toUShort(nullptr, 16);
    pkg.data = val.toUInt(nullptr, 16);
    Mcu::getInstance()->sendSensorRegisterOperation(pkg);
}


/**
 * @brief ImageSettingUi::读Sensor
 */
void ImageSettingUi::on_pushButton_4_clicked() {
    SensorRegisterOperationPkg pkg;
    QString txt = ui->lineEdit_3->text();
    pkg.operation = 0;
    pkg.addr = txt.toUShort(nullptr, 16);
    Mcu::getInstance()->sendSensorRegisterOperation(pkg);
}


void ImageSettingUi::setMaskType() {
    auto m_sensorType = SensorInfo::getInstance().getSensorType();
    int mirrorType = RuntimeData::BootSetting::getInstance()->g_bootSettingInfo.currentMirrorType;
    int v = RuntimeData::ImageSetting::getInstance()->g_settingItemValue[mirrorType][10];
    if(m_sensorType == 0x69) {
        if(v == 0) {
            ui->image->setStyleSheet("background-color: rgb(0, 0, 0);"
                                          "border-image: url(:/image/rectMask.png);");
        } else if( v == 2) {
            ui->image->setStyleSheet("background-color: rgb(0, 0, 0);"
                                          "border-image: url(:/image/roundMask.png);");
        } else {
            ui->image->setStyleSheet("background-color: rgb(0, 0, 0);"
                                          "border-image: url(:/image/rect45Mask.png);");
        }
    } else {
        ui->image->setStyleSheet("background-color: rgb(0, 0, 0);");
    }
}
